#include "timer.h"
#include <cstring>


template<typename ...Ts>
__always_inline void timer_entry_print(FILE *f, const timer_entry_tmpl<Ts...> *entry){
  fprintf(f, "|%-24s", entry->name);
  fprintf(f, "|%10d|", entry->ncalls);
  const char *fmt[sizeof...(Ts)] = {Ts::fmt...};
  for (int i = 0; i < sizeof...(Ts); i ++) {
    fprintf(f, fmt[i], entry->value[i]);
    fprintf(f, "|");
  }
  fprintf(f, "\n");
}

template<typename ...Ts>
__always_inline void print_header(FILE *f, const timer_entry_tmpl<Ts...> *entry) {
  char dashes[32];
  memset(dashes, '-', 32);
  fprintf(f, "+%-.24s+%.10s+", dashes, dashes);
  for (int i = 0; i < sizeof...(Ts); i ++) {
    fprintf(f, "%.16s+", dashes);
  }
  fprintf(f, "\n");

  const char *name[sizeof...(Ts)] = {Ts::name...};
  fprintf(f, "|%-24.24s|%10.10s|", "timer name", "#calls");

  for (int i = 0; i < sizeof...(Ts); i ++) {
    fprintf(f, "%16.16s|", name[i]);
  }
  fprintf(f, "\n");

  fprintf(f, "+%-.24s+%.10s+", dashes, dashes);
  for (int i = 0; i < sizeof...(Ts); i ++) {
    fprintf(f, "%.16s+", dashes);
  }
  fprintf(f, "\n");
}
void timer_fprint(FILE *f){
  print_header(f, timer_entry::all[0]);

  for (int i = 0; i < timer_entry::all.size(); i ++) {
    timer_entry_print(f, timer_entry::all[i]);
  }
  print_header(f, timer_entry::all[0]);
  fprintf(f, "\n");
}